/* @flow */

import config from '../config'
import {
  initUse
} from './use'
import {
  initMixin
} from './mixin'
import {
  initExtend
} from './extend'
import {
  initAssetRegisters
} from './assets'
import {
  set,
  del
} from '../observer/index'
import {
  ASSET_TYPES
} from 'shared/constants'
import builtInComponents from '../components/index'
import {
  observe
} from 'core/observer/index'

import {
  warn,
  extend,
  nextTick,
  mergeOptions,
  defineReactive
} from '../util/index'

// 
export function initGlobalAPI(Vue: GlobalAPI) {
  // config
  // 属性的一些约束规则
  const configDef = {}
  configDef.get = () => config

  if (process.env.NODE_ENV !== 'production') {
    configDef.set = () => {
      // 不要给config重新赋值，改为设置单个字段。
      warn(
        'Do not replace the Vue.config object, set individual fields instead.'
      )
    }
  }

  // 定义了一个config属性 --- Vue.config  静态成员
  Object.defineProperty(Vue, 'config', configDef)

  // exposed util methods.
  // NOTE: these are not considered part of the public API - avoid relying on
  // them unless you are aware of the risk.
  // 静态成员 util对象中放一些公用的方法
  // 这些工具方法不是全局API,是框架内部使用；除非自己意识到某些方法，否则不建议使用。
  Vue.util = {
    warn,
    extend,
    mergeOptions,
    defineReactive
  }

  // vue静态方法 set/delete/nextTick
  // nextTick获取更新后的DOM的Vue方法,可以用来操作dom --- 响应式相关
  Vue.set = set
  Vue.delete = del
  Vue.nextTick = nextTick

  // 2.6 explicit observable API
  // 响应式对象
  Vue.observable = < T > (obj: T): T => {
    observe(obj)
    return obj
  }

  // 不需要原型的对象，可以提高性能
  Vue.options = Object.create(null)
  // components/directives/filters
  ASSET_TYPES.forEach(type => {
    Vue.options[type + 's'] = Object.create(null)
  })

  // this is used to identify the "base" constructor to extend all plain-object
  // components with in Weex's multi-instance scenarios.
  Vue.options._base = Vue

  // 把一个对象的属性拷贝到另外一个对象中 
  // 浅拷贝 --- 设置keepAlive组件
  extend(Vue.options.components, builtInComponents)

  // Vue.use()
  initUse(Vue)
  // Vue.mixin()
  initMixin(Vue)
  // Vue.extend()  基于传入的options返回一个组件的构造函数
  initExtend(Vue)
  // 注册Vue.directive()/Vue.component()/Vue.filter()   三个静态成员参数一样
  initAssetRegisters(Vue)
}
